package ycl.base.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import ycl.base.entity.Files;
import ycl.base.entity.PublicFiles;
import ycl.base.mapper.FilesMapper;
import ycl.base.mapper.PublicFilesMapper;
import ycl.base.req.FilesReq;
import ycl.base.res.FilesRes;
import ycl.base.service.FilesService;
import ycl.base.service.PublicFilesService;
import ycl.base.service.UserFilesService;
import ycl.base.utils.UploadFileData;
import ycl.base.utils.UploadFileUtil;
import ycl.common.base.service.impl.BaseServiceImpl;
import ycl.common.enums.FileTypeEnum;
import ycl.common.models.res.hovel.UploadRes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author ycl
 * @since 2022-06-30 18:33:18
 */
@Service
@Slf4j
public class FilesServiceImpl extends BaseServiceImpl
		<FilesMapper, Files, FilesReq, FilesRes>
		implements FilesService {

	@Resource
	private FilesMapper filesMapper;
	@Value("${file.path.absolute}")
	private String prefix;
	@Resource
	private PublicFilesMapper publicFilesMapper;
	@Resource
	private UserFilesService userFilesService;
	@Resource
	private PublicFilesService publicFilesService;



	@Override
	@Transactional(rollbackFor = Exception.class)
	public UploadRes upload(HttpServletRequest request, MultipartFile file, FileTypeEnum type) {
		Long userId = getUserId(request);
		UploadFileData uploadData = UploadFileUtil.getUploadData(userId, file, type, prefix);
		//判断文件大小, 大文件用秒传 + 断点续传, 小文件直接上传到用户目录
		Long size = uploadData.getFileSize();

		UploadRes res = new UploadRes()
				.setFileName(uploadData.getFilename())
				.setFileUrl(uploadData.getUserOutPath());

		//文件小于50M, 直接上传到用户私有路径下, 先保存到数据库
		if ((size / 1000 / 1000) < 50) {
			userFilesService.upload(userId, uploadData, file);
			return res;
		}
		//文件大于50M, 上传到公共路径, 再复制到用户私有路径. 先根据密文看看公共文件里有没有
		String crypto = uploadData.getCrypto();
		PublicFiles publicFiles = publicFilesMapper.selectByCrypto(crypto);
		//有就复制, 并新增数据到数据库里
		if (publicFiles != null) {
			uploadData.setFileUuidName(publicFiles.getName());
			userFilesService.saveAndCopyToUserFold(userId, uploadData);
			return res;
		}
		//没有就上传, 先上传到公共目录, 再保存到用户的路径
		publicFilesService.upload(uploadData, file);
		userFilesService.saveAndCopyToUserFold(userId, uploadData);
		return res;
	}


}
